import 'package:flutter_iot_plugin/flutter_iot_plugin.dart';
import 'package:flutter_iot_plugin/pigeon.dart';
import 'package:get/get.dart';

import 'add_device_state.dart';
import 'found_device_state.dart';

class AddDeviceController extends GetxController {
  static AddDeviceController instance = AddDeviceController._();

  factory AddDeviceController() => instance;

  AddDeviceController._();

  String productKey = "";
  String productId = "";
  String wifiName = "";
  String wifiSsid = "";
  var timeout = 30;
  var authCodeLoginSuccess = false.obs;

  var addDeviceState = AddDeviceState();
  var foundDeviceState = FoundDeviceState();

  void init(productKey, String productId, String wifiName, String wifiSsid) {
    this.productKey = productKey;
    this.productId = productId;
    this.wifiName = wifiName;
    this.wifiSsid = wifiSsid;

    FlutterIotPlugin.instance.addDeviceListener = FlutterAliLinkListener();
  }


  void startDiscovery() {
    FlutterIotPlugin.instance.stopDiscovery();
    FlutterIotPlugin.instance.startDiscovery();
  }

  void stopDiscovery() {
    FlutterIotPlugin.instance.stopDiscovery();
  }

  void startAddDeviceByBroadcast() {
    FlutterIotPlugin.instance.stopAddDevice();
    FlutterIotPlugin.instance.startAddDeviceByBroadcast(productKey, productId);
  }

  void startAddDeviceBySoftAP() {
    FlutterIotPlugin.instance.stopAddDevice();
    FlutterIotPlugin.instance.startAddDeviceBySoftAP(productKey, productId);
  }

  void startAddDeviceByBLE() {
    FlutterIotPlugin.instance.stopAddDevice();
    FlutterIotPlugin.instance.startAddDeviceByBLE(productKey, productId);
  }

  void stopAddDevice() {
    FlutterIotPlugin.instance.stopAddDevice();
    addDeviceState.step.value = AddDeviceStep.onStop;
    update();
  }

  void getToken(String deviceName, String productKey, int timeout, int interval) {
    addDeviceState.step.value = AddDeviceStep.onGetToken;
    FlutterIotPlugin.instance.getDeviceToken(deviceName, productKey, timeout, interval);
    update();
  }

  void getIotId(String token) {
    addDeviceState.step.value = AddDeviceStep.onGetIotId;
    FlutterIotPlugin.instance.getIotId(token);
    update();
  }

  void authCodeLogin(String authCode) {
    FlutterIotPlugin.instance.authCodeLogin(authCode);
  }
  void getDeviceToken(String productKey) {
    FlutterIotPlugin.instance.getDeviceToken("",productKey,60 * 1000,5*1000);
  }
}

class FlutterAliLinkListener extends FlutterAliLink {
  var controller = AddDeviceController.instance;

  @override
  void onPreCheck(int result, DCErrorCode? dcErrorCode) {
    controller.addDeviceState.code.value = dcErrorCode?.code?.toString() ?? "";
    controller.addDeviceState.subcode.value = dcErrorCode?.subcode?.toString() ?? "";
    controller.addDeviceState.codeName.value = dcErrorCode?.codeName?.toString() ?? "";
    controller.addDeviceState.step.value = AddDeviceStep.onPreCheck;
    controller.update();
  }

  @override
  void onProvisionPrepare(int prepareType) {
    controller.addDeviceState.prepareType = prepareType;
    controller.addDeviceState.step.value = AddDeviceStep.onProvisionPrepare;
    controller.update();

    if (prepareType == 1) {
      FlutterIotPlugin.instance.toggleProvision(controller.wifiName, controller.wifiSsid, controller.timeout);
    } else if (prepareType == 2) {
      //提示用户连接热点
    }
    controller.update();
  }

  @override
  void onProvisionStatus(int code, String msg) {
    controller.addDeviceState.code.value = code.toString();
    controller.addDeviceState.msg.value = msg;
    controller.addDeviceState.step.value = AddDeviceStep.onProvisionStatus;
    controller.update();
  }

  @override
  void onProvisionedResult(int success, DeviceInfo? deviceInfo, DCErrorCode? dcErrorCode) {
    controller.addDeviceState.result.value = success == 1;
    controller.addDeviceState.productKey.value = deviceInfo?.productKey ?? "";
    controller.addDeviceState.deviceName.value = deviceInfo?.deviceName ?? "";
    controller.addDeviceState.step.value = AddDeviceStep.onProvisionedResult;
    controller.update();

    if (success == 1) {
      var deviceName = deviceInfo?.deviceName ?? "";
      var productKey = deviceInfo?.productKey ?? "";
      var timeout = 60 * 1000;
      var interval = 5 * 1000;
      controller.getToken(deviceName, productKey, timeout, interval);
    }
  }

  @override
  void onProvisioning() {
    controller.addDeviceState.step.value = AddDeviceStep.onProvisioning;
    controller.update();
  }

  @override
  void onDeviceFound(int type, String? description, List<DeviceInfo?>? deviceInfos) {
    if (deviceInfos != null) {
      controller.foundDeviceState.foundDeviceInfos = deviceInfos;
      controller.update();
    }
  }

  @override
  void getDeviceTokenOnFail(DCErrorCode dcErrorCode) {
    controller.addDeviceState.step.value = AddDeviceStep.onGetTokenFail;
    controller.update();
  }

  @override
  void getDeviceTokenOnSuccess(GetTokenResult getTokenResult) {
    controller.addDeviceState.step.value = AddDeviceStep.onGetTokenSuccess;
    controller.addDeviceState.token.value = getTokenResult.token ?? "";
    controller.update();
    print("getDeviceTokenOnSuccess");
  }

  @override
  void onAuthCodeLoginFailed(int code, String msg) {
    print("onAuthCodeLoginFailed,code=$code,msg=$msg");
  }

  @override
  void onAuthCodeLoginSuccess() {
    print("onAuthCodeLoginSuccess");
    controller.update();
  }

  @override
  void onGetIotIdResult(int result, String? iotId) {
    print("onGetIotIdResult,result=$result,iotId=$iotId");
    if (result == 1) {
      controller.addDeviceState.step.value = AddDeviceStep.onGetIotIdSuccess;
    } else {
      controller.addDeviceState.step.value = AddDeviceStep.onGetTokenFail;
    }
    controller.update();
  }
}
